package com.cookman.gameobjects;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.InputListener;
import com.badlogic.gdx.scenes.scene2d.Touchable;
import com.cookman.assets.AssetCity;
import com.cookman.assets.AssetFonts;
import com.cookman.assets.AssetsImpl;
import com.cookman.assets.AssetsLocator;
import com.cookman.controllers.AliceUI;
import com.cookman.factories.CitiesFactory;
import com.cookman.renderers.WorldRenderer;
import com.cookman.serviceLocators.ServiceLocator;
import com.cookman.utils.AssetUtils;
import com.cookman.utils.Constants;
import com.cookman.world.entities.City;
import com.cookman.world.entities.Disease;
import com.cookman.world.entities.Player;

import java.util.Collections;
import java.util.List;

/**
 * Created by Cookman on 03.05.14.
 */

public class CityActor extends AbstractGameObject {

    private List<Player> players;
    private City city;
    private String id;
    private boolean advancedLine = false;

    private Boolean isActive = true;
    private Boolean isSelected = false;
    private Sprite activeSprite;
    private Sprite inactiveSprite;
    Sprite labSprite = AssetsLocator.getSpriteByAtlasRegion(AssetsImpl.CITY, AssetCity.LAB);

    private DiseaseActor disease = new DiseaseActor();

    private float scale = 0.14f;

    public CityActor() {
        setBounds(0, 0, scale, scale);
        addListener(mouseActorListener);
        setTouchable(Touchable.enabled);
    }

    public void setIsActive(Boolean isActive) {
        this.isActive = isActive;
    }

    public void setIsSelected(Boolean isSelected) {
        this.isSelected = isSelected;
    }

    public boolean isAdvancedLine() {
        return advancedLine;
    }

    public Boolean getIsActive() {
        return isActive;
    }

    public Boolean getIsSelected() {
        return isSelected;
    }

    public String getId() {
        return id;
    }

    public City getCity() {
        return city;
    }

    public void setPlayers(List<Player> players) {
        this.players = players;
    }

    public void setCity(City city) {
        this.city = city;
        activeSprite = AssetUtils.getActiveCityAssetsByColor(city.getColor());
        inactiveSprite = AssetUtils.getInactiveCityAssetsByColor(city.getColor());
    }

    private static InputListener mouseActorListener = new InputListener() {
        // коснулись актера
        @Override
        public boolean touchDown(InputEvent event, float x, float y,
                                 int pointer, int button) {
            return true; // обязательно возвращаем true - чтобы был вызван потом метод touchUp()
        }

        // отпустили мышку или подняли палец с актера
        @Override
        public void touchUp(InputEvent event, float x, float y, int pointer,
                            int button) {
            if (!((AliceUI) ServiceLocator.getUIController()).canSelectCities() || ServiceLocator.getWorldRenderer().isModalVisible())
                return;
            CityActor actor = (CityActor) event.getTarget();

            if (actor.isActive) {
                ServiceLocator.getUIController().resetSelectedCities();
                actor.setIsSelected(!actor.getIsSelected());
                ServiceLocator.getUIController().selectCity(actor);
            }
        }

        @Override
        public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) {
            super.enter(event, x, y, pointer, fromActor);
        }
    };

    private String[] colors=new String[]{ Disease.BLACK,Disease.BLUE, Disease.RED,Disease.YELLOW};
    @Override
    public void draw(Batch batch, float parentAlpha) {
        getCurrentSprite().getTexture().setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
        if (isSelected) {
            batch.draw(getCurrentSprite(), getX(), getY(), scale * 1.3f, scale * 1.3f);
        } else {
            batch.draw(getCurrentSprite(), getX(), getY(), scale, scale);
        }
        float padding=0;
        for(String color: colors) {
            if(city.getDiseaseCountByColor(color)>0) {
                drawDiseases(batch, color,padding);
                padding+=0.03f;
            }
        }

        if (getCity().getHasLab()) {
            batch.draw(labSprite, getX() + 0.1f, getY() + 0.1f, scale / 2, scale / 2);
        }


        drawPlayers(batch);
    }

    private void drawDiseases(Batch batch, String color,float padding) {
        disease.draw(batch, getX() - 0.04f+padding, getY()-padding, color, city.getDiseaseCountByColor(color));
    }

    private float playerScale = 0.05f;

    private float playerAlpha = 1;

    private void drawPlayers(Batch batch) {
        if (players == Collections.EMPTY_LIST) return;
        float posX = getX() + 0.05f;

        playerAlpha = playerAlpha - 0.1f;

        for (Player player : players) {
            Sprite playerSprite = AssetUtils.getPlayerSprite(player);
            batch.draw(playerSprite, posX, getY() - 0.05f, playerScale, (playerScale * playerSprite.getHeight()) / playerSprite.getWidth());
            posX += playerScale + 0.05;
        }
    }

    private Sprite getCurrentSprite() {
        return isActive ? activeSprite : inactiveSprite;
    }

    @Override
    public void renderGUI(SpriteBatch batch) {
        float x1 = WorldRenderer.cameraGUI.position.x - WorldRenderer.ratew * (WorldRenderer.camera.position.x - getX() - scale);
        float y1 = WorldRenderer.cameraGUI.position.y + WorldRenderer.rateh * (WorldRenderer.camera.position.y - getY() - scale);
        AssetFonts.font.setScale(0.2f);
        AssetFonts.font.setColor(Color.BLACK);
        String stat = city.getName();
        AssetFonts.font.draw(batch, stat, x1 - 10, y1);
    }

    @Override
    public void renderShape(ShapeRenderer renderer) {
        float padding = scale / 2;
        Gdx.gl20.glLineWidth(2);
        float lineWidth = 0.015f;

        renderer.end();
        renderer.setColor(Color.LIGHT_GRAY);
        renderer.begin(ShapeRenderer.ShapeType.Filled);

        for (City neighbour : this.city.getNeighbours()) {
            CityActor neighbourCity = CitiesFactory.findWorldCityById(neighbour.getId());
            if (neighbourCity != null) {
                renderer.identity();
                if (getX() >= neighbourCity.getX() && (getX() - neighbourCity.getX()) > 1f && advancedLine && neighbourCity.isAdvancedLine()) {
                    renderer.rectLine(getX() + padding, getY() + padding, getX() + Constants.VIEWPORT_WIDTH / 4, neighbourCity.getY() + padding, lineWidth);
                } else if (getX() <= neighbourCity.getX() && (neighbourCity.getX() - getX()) > 1f && advancedLine && neighbourCity.isAdvancedLine()) {
                    renderer.rectLine(getX() + padding, getY() + padding, -Constants.VIEWPORT_WIDTH / 4, neighbourCity.getY() + padding, lineWidth);
                } else {
                    renderer.rectLine(getX() + padding, getY() + padding, neighbourCity.getX() + padding, neighbourCity.getY() + padding, lineWidth);
                }
            }
        }
        if (Constants.INDEBUG) {
            renderer.rect(getX(), getY(), scale, scale);
        }
        renderer.end();
    }
}